<html>
    <head>
        <title>当前主体  ICurrentPrincipalAccessor</title>
    </head>
    <body>
        <script>
             /*
                        五、当前主体接口 ICurrentPrincipalAccessor

                                ICurrentPrincipalAccessor 是当需要使用当前用户的当前主体(Principal)时使用的接口。

                                用来获取当前用户的当前主体。

                                对于Web应用程序而言，它获取当前 HttpContext 的 User属性。

                                对于非Web应用程序，它返回 Thread.CurrentPrincipal。


                                你通常不需要使用这种底层的 ICurrentPrincipalAccessor 服务，只需要使用上面的 ICurrentUser 服务就好。


                                1、基本用法：

                                        你可以将ICurrentPrincipalAccessor注入并使用Principal属性到当前主体：

                                            eg:

                                                public class MyService : ITransientDependency
                                                {
                                                    private readonly ICurrentPrincipalAccessor _currentPrincipalAccessor;

                                                    public MyService(ICurrentPrincipalAccessor currentPrincipalAccessor)
                                                    {
                                                        _currentPrincipalAccessor = currentPrincipalAccessor; // 注入 ICurrentPrincipalAccessor 服务
                                                    }
                                                    
                                                    public void Foo()
                                                    {
                                                        // 获取当前主题的所有声明
                                                        var allClaims = _currentPrincipalAccessor.Principal.Claims.ToList();
                                                    }
                                                }

                                2、更改当前主题：

                                        当前主体不是你想要设置或更改的对象，除非在某些高级方案中。

                                        如果需要，请使用ICurrentPrincipalAccessor的Change方法。它接受一个ClaimsPrincipal对象，并将其设为范围的“当前”。


                                        eg:
                                            public class MyAppService : ApplicationService
                                            {
                                                private readonly ICurrentPrincipalAccessor _currentPrincipalAccessor;

                                                public MyAppService(ICurrentPrincipalAccessor currentPrincipalAccessor)
                                                {
                                                    _currentPrincipalAccessor = currentPrincipalAccessor;
                                                }

                                                public void Foo()
                                                {
                                                    // 创建一个新的ClaimsPrincipal对象，并将其设置为当前主体。
                                                    var newPrincipal = new ClaimsPrincipal(
                                                        new ClaimsIdentity(
                                                            new Claim[]
                                                            {
                                                                new Claim(AbpClaimTypes.UserId, Guid.NewGuid().ToString()),
                                                                new Claim(AbpClaimTypes.UserName, "john"),
                                                                new Claim("MyCustomCliam", "42")
                                                            }
                                                        )
                                                    );

                                                    // 始终在using语句中使用Change方法，因此在using范围结束后，它将恢复为原始值。
                                                    using (_currentPrincipalAccessor.Change(newPrincipal))
                                                    {
                                                        var userName = CurrentUser.UserName; //returns "john"
                                                        //...
                                                    }
                                                }
                                            }

                                        始终在using语句中使用Change方法，因此在using范围结束后，它将恢复为原始值。

                                        这可能是一种模拟应用程序代码作用域的用户登录的方法，但是请谨慎使用它。
                    */
        </script>
    </body>
</html>